﻿using ProjectFootball.MVC.Areas.PersonArea.Models;
using ProjectFootball.MVC.Foundation;
using ProjectFootball.MVC.Foundation.ResourceLibrary;
using ProjectFootball.MVC.Models.EntityFramework.Entities;
using ProjectFootball.MVC.Models.RepositoryProviders;
using System;
using System.Linq;
using System.Security.Principal;
using System.Web.Mvc;

namespace ProjectFootball.MVC.Areas.PersonArea.Controllers
{
    [Authorize]
    public class EditorController : BaseController
    {
        #region Constructor
        public EditorController(IRepositoryProvider provider)
            :base(provider)
        {
        }
        #endregion

        #region /PersonArea/Editor
        public ActionResult Index(Guid id)
        {
            var person = Provider.PersonRepository.SearchByPrimaryKey(id);

            if (person == null)
                return RedirectHome;

            return View(person.GetDataModel());
        }

        [HttpPost]
        [ValidateAntiForgeryToken]
        public ActionResult Index(PersonDataModel personDataModel)
        {
            if (!ModelState.IsValid)
                return View(personDataModel);

            var person = Provider.PersonRepository.SearchByPrimaryKey(personDataModel.PersonGuid);

            if (person.CanEdit(User))
                person.Edit(personDataModel, User);
            else
            {
                person = personDataModel.CreateUnapproved(User);
                Provider.PersonRepository.Add(person);
            }

            Provider.SaveChanges();

            return RedirectToAction("Index", "Details", new { id = person.Pk });
        }
        #endregion

        #region /PersonArea/Editor/CreateNew
        public ActionResult CreateNew()
        {
            return View("Index", new PersonDataModel());
        }

        [HttpPost]
        [ValidateAntiForgeryToken]
        public ActionResult CreateNew(PersonDataModel personDataModel)
        {
            if (!ModelState.IsValid)
                return View("Index", personDataModel);

            var person = personDataModel.CreateNew(User);

            Provider.PersonRepository.Add(person);

            Provider.SaveChanges();
            return RedirectToAction("Index", "Details", new { id = person.Pk });
        }
        #endregion

        #region /CountryArea/Editor/Delete
        public ActionResult Delete(Guid id)
        {
            var person = Provider.PersonRepository.SearchByPrimaryKey(id);

            if (person == null || !person.CanDelete(User))
                return View(false);

            Provider.PersonRepository.Remove(person);
            Provider.SaveChanges();

            return RedirectToAction("Index", "Home", new { area = string.Empty });
        }
        #endregion

        #region /PersonArea/Editor/RecordForApproval
        [Authorize(Roles = "Admin, Superuser")]
        public ActionResult RecordForApproval(Guid id)
        {
            var person = Provider.PersonRepository.SearchByPrimaryKey(id);
            var people = Provider.PersonRepository.Where(c => c.ApprovalGuid == person.ApprovalGuid);

            return View("Approval", people.Search(User, SearchType.RecordForApproval));
        }
        #endregion

        #region /PersonArea/Editor/ConfirmApproval
        [Authorize(Roles = "Admin, Superuser")]
        public ActionResult ConfirmApproval(Guid id)
        {
            if (!User.IsApprover())
                return View(false);

            var person = Provider.PersonRepository.SearchByPrimaryKey(id);

            if (person == null || !person.CanApprove(User))
                return RedirectHome;

            var personQuery = from c in Provider.PersonRepository.Where(c => c.ApprovalGuid == person.ApprovalGuid && c.IsApproved)
                              select c;

            Guid approvedPersonGuid;

            if (personQuery.Any())
            {
                var approvedPerson = personQuery.Single();

                approvedPersonGuid = approvedPerson.Pk;
                person.Approve(approvedPerson);

                Provider.SaveChanges();
            }
            else
            {
                person.IsApproved = true;
                approvedPersonGuid = person.Pk;
                Provider.SaveChanges();
            }

            var people = Provider.PersonRepository.Where(c => c.ApprovalGuid == person.ApprovalGuid && !c.IsApproved);
            Provider.PersonRepository.RemoveAll(people);

            Provider.SaveChanges();

            return RedirectToAction("Index", "Details", new { id = approvedPersonGuid });
        }
        #endregion

        #region PersonArea/Editor/PendingApprovals
        [Authorize(Roles = "Admin, Superuser")]
        public ActionResult PendingApprovals()
        {
            var people = Provider.PersonRepository.Where(c => c.IsApproved == false);

            return View("Approval", people.Search(User, SearchType.PendingApprovals));
        }
        #endregion
    }
}
